package com.inibb.app.service.security.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.inibb.app.converter.Db2VOConverter;
import com.inibb.app.converter.RoleConverter;
import com.inibb.app.dao.JpaGenericDao;
import com.inibb.app.dao.api.IDao;
import com.inibb.app.po.security.Role;
import com.inibb.app.service.security.IRoleService;
import com.inibb.app.vo.security.RoleDTO;

@Service
@Transactional
public class RoleServiceImpl implements IRoleService {
	
//	private HibernateDaoSupport authorityDao;
//	private SimpleHibernateTemplate<Role, Integer> roleDao;
	private IDao<Role, Integer> roleDao;
	
	@PersistenceContext(unitName = "entityManager")
	private EntityManager entityManager ;
		
	@Autowired
	public void setEntityManagerFactory() {
		roleDao = new JpaGenericDao<Role, Integer>(entityManager, Role.class);
	}
	
	private RoleConverter converter = new RoleConverter();
	
	public Collection<RoleDTO> getAllRoles() {
		List<Object[]> objs = roleDao.queryNativeSqlForList("admin", "searchRole", null);
		List<RoleDTO> gcList = new ArrayList<RoleDTO>();
		for(Object[] obj:objs){
			gcList.add(Db2VOConverter.toVO4Role(obj));
		}
		return gcList;
	}
	@Override
	public Collection<RoleDTO> getDefaultRoles() {
		Map<String, Object> criteria = new HashMap<String, Object>();
		criteria.put("isDefault", "Y");
		List<Object[]> objs = roleDao.queryNativeSqlForList("admin", "searchDefaultRole", criteria);
		List<RoleDTO> gcList = new ArrayList<RoleDTO>();
		for(Object[] obj:objs){
			gcList.add(Db2VOConverter.toVO4Role(obj));
		}
		return gcList;
	}
	public Collection<RoleDTO> searchRolesByUserId(Integer userId) {
		Map<String, Object> criteria = new HashMap<String, Object>();
		criteria.put("userId", userId);
		List<Object[]> objs = roleDao.queryNativeSqlForList("admin", "searchRole", criteria);
		List<RoleDTO> gcList = new ArrayList<RoleDTO>();
		for(Object[] obj:objs){
			gcList.add(Db2VOConverter.toVO4Role(obj));
		}
		return gcList;
	}
/*
	public void delete(RoleVO roleVO) {
		
		Role role = (Role) roleDao.getSession().merge(RoleConvertor.toPO(roleVO)); 
		
		roleDao.delete(role);
	}



	public Collection<RoleVO> getRoleBy(PageFilter filter, PageSort sort) {
		HibernateFilter Hfilter = FilterUtils.toHibernateFilter(filter);
		HibernateSort Hsort = SortUtils.toHibernateSort(sort);
		Criteria criteria = roleDao.getSession().createCriteria(Role.class);
		criteria = Hfilter.execute(criteria);
		criteria = Hsort.execute(criteria);
		criteria.setFirstResult(filter.getRowStart());
		criteria.setMaxResults(filter.getRowEnd() - filter.getRowStart());

		return (Collection<RoleVO>) criteria.list();
	}

	public RoleVO getRoleById(String id) {
		Long idLong = Long.parseLong(id);
		return RoleConvertor.toVO(roleDao.findUniqueByProperty("id", idLong));
	}

	public RoleVO getRoleByName(String name) {
		return RoleConvertor.toVO(roleDao.findUniqueByProperty("name", name));
	}

	public int getRoleCountBy(PageFilter filter, PageSort sort) {
		HibernateFilter Hfilter = FilterUtils.toHibernateFilter(filter);
		Criteria criteria = roleDao.getSession().createCriteria(Role.class);
		criteria = Hfilter.execute(criteria);
		criteria.setProjection(Projections.rowCount()).uniqueResult();
		return ((Integer) criteria.uniqueResult()).intValue();
	}

	public void save(RoleVO roleVO) throws Exception {
		
		String name = roleVO.getName();

		// Check Data Base: If there was a role with the same name or not.
		if (roleDao.findUniqueByProperty("name", name) != null) {
			String msg = "Role \"" + name
					+ "\" already exist. Please try another name.";
			throw new Exception(msg);
		}

		try {
			Role role = (Role) roleDao.getSession().merge(RoleConvertor.toPO(roleVO)); 
			roleDao.save(role);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	public void update(RoleVO roleVO) throws Exception {
		
		String name = roleVO.getName();

		Role tempRole = roleDao.findUniqueByProperty("name", name);

		// Check Data Base: If there was a role with the same name or not.
		if ((tempRole != null) && !(tempRole.getId().equals(roleVO.getId()))) {
			String msg = "Role \"" + name
					+ "\" already exist. Please try another name.";
			throw new Exception(msg);
		}

		try {
			Role role = (Role) roleDao.getSession().merge(RoleConvertor.toPO(roleVO)); 
			roleDao.update(role);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	public Boolean idBunded(RoleVO roleVO) {
		List<UserRoleRel> l = userRoleDao.findByProperty("roleId", roleVO
				.getId());

		if (l.size() == 0)
			return false;

		return true;
	}
*/
	@Override
	public String[] getDefaultRoleIds() {
		Collection<RoleDTO> roles = this.getDefaultRoles();
		List<String> ls = new ArrayList<String>();
		for(RoleDTO role:roles){
			ls.add(String.valueOf(role.getId()));
		}
		return ls.toArray(new String[0]);
	}
}
